package com.gitee.feizns.quickstart.domain.query;

import com.gitee.feizns.dynamic.Ref;
import com.gitee.feizns.dynamic.bean.Getter;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.function.BiFunction;
import java.util.stream.Collectors;

/**
 * 关系
 * @author feizns
 * @since 2025/8/8
 */
public interface Relationship<T, M, S> {

    /**
     * 关系生成器引用
     */
    Ref<BiFunction<Getter<Object, Object>, Getter<Object, Object>, Relationship<Object, Object, Object>>> generator = Ref.of(null);

    /**
     * 获取主表编号
     * @return {@link M }
     */
    default M getMainId() {
        throw new UnsupportedOperationException("getMainId method is not implemented.");
    }

    /**
     * 设置主要编号
     * @param mainId 主要编号
     */
    default void setMainId(M mainId) {
        throw new UnsupportedOperationException("setMainId method is not implemented.");
    }

    /**
     * 关联表操作
     * @param mainField 主字段
     * @param subField  子字段
     * @return {@link Relationship }<{@link T }, {@link M }, {@link S }>
     */
    @SuppressWarnings("unchecked")
    static <T, M, S> Relationship<T, M, S> of(Getter<T, M> mainField, Getter<T, S> subField) {
        if ( generator.isNull() )
            throw new IllegalStateException("Relationship ref is not set. Please set it before using this method.");
        return (Relationship<T, M, S>) generator.get().apply((Getter<Object, Object>) mainField, (Getter<Object, Object>) subField);
    }

    /**
     * 关联表操作
     * @param mainField 主字段
     * @param subField  子字段
     * @return {@link Relationship }<{@link T }, {@link M }, {@link S }>
     */
    static <T, M, S> Relationship<T, M, S> of(Getter<T, M> mainField, M mainId, Getter<T, S> subField) {
        Relationship<T, M, S> relationship = of(mainField, subField);
        relationship.setMainId(mainId);
        return relationship;
    }

    /**
     * 过滤器（添加该字段作为条件，新增时也会添加上改字段值）
     * @param field 字段名称
     * @param value 值
     * @return {@link Relationship }<{@link T }, {@link M }, {@link S }>
     */
    Relationship<T, M, S> filter(Getter<T, ?> field, Object value);

    /**
     * 重置关系
     * @param id        编号
     * @param newSubIds 子表ID
     * @return boolean
     */
    @SuppressWarnings("unchecked")
    default boolean reset(M id, S... newSubIds) {
        return reset(id, Arrays.asList(newSubIds));
    }

    /**
     * 重置
     * @param newSubId 新增功能子编号
     * @return boolean
     */
    @SuppressWarnings("unchecked")
    default boolean reset(S newSubId) {
        return reset(getMainId(), newSubId);
    }

    /**
     * 重置关系
     * @param id        编号
     * @param newSubIds 子表ID
     * @return boolean
     */
    default boolean reset(M id, Collection<? extends S> newSubIds) {
        clear(id);
        return add(id, newSubIds) > 0;
    }

    /**
     * 重置
     * @param newSubIds 新增功能子编号
     * @return boolean
     */
    default boolean reset(Collection<? extends S> newSubIds) {
        return reset(getMainId(), newSubIds);
    }

    /**
     * 添加关系
     * @param id        主表编号
     * @param newSubIds 子表ID
     * @return int
     */
    @SuppressWarnings("unchecked")
    default int add(M id, S... newSubIds) {
        return add(id, Arrays.asList(newSubIds));
    }

    /**
     * 添加关系
     * @param newSubIds 子表ID
     * @return int
     */
    @SuppressWarnings("unchecked")
    default int add(S... newSubIds) {
        return add(getMainId(), newSubIds);
    }

    /**
     * 添加关系
     * @param id        主表编号
     * @param newSubIds 子表ID
     * @return int
     */
    int add(M id, Collection<? extends S> newSubIds);

    /**
     * 添加关系
     * @param newSubIds 子表ID
     * @return int
     */
    default int add(Collection<? extends S> newSubIds) {
        return add(getMainId(), newSubIds);
    }

    /**
     * 删除指定关系
     * @param mainId 主表编号
     * @param subIds 子表ID
     * @return boolean
     */
    @SuppressWarnings("unchecked")
    default boolean delete(M mainId, S... subIds) {
        return delete(mainId, Arrays.asList(subIds));
    }

    /**
     * 删除指定关系
     * @param subIds 子表ID
     * @return boolean
     */
    @SuppressWarnings("unchecked")
    default boolean delete(S... subIds) {
        return delete(getMainId(), subIds);
    }

    /**
     * 删除指定关系
     * @param mainId 主表编号
     * @param subIds 子表ID
     * @return boolean
     */
    boolean delete(M mainId, Collection<? extends S> subIds);

    /**
     * 删除指定关系
     * @param subIds 子表ID
     * @return boolean
     */
    default boolean delete(Collection<? extends S> subIds) {
        return delete(getMainId(), subIds);
    }

    /**
     * 清空主表字段为指定值的关系
     * @param mainId 主表编号
     * @return boolean
     */
    boolean clear(M mainId);

    /**
     * 清空主表字段为指定值的关系
     * @return boolean
     */
    default boolean clear() {
        return clear(getMainId());
    }

    /**
     * 列表（获取所有的指定主表值的所有关联关系）
     * @param mainId 主表编号
     * @return {@link List }<{@link T }>
     */
    List<T> list(M mainId);

    /**
     * 列表（获取所有的指定主表值的所有关联关系）
     * @return {@link List }<{@link T }>
     */
    default List<T> list() {
        return list(getMainId());
    }

    /**
     * 获取指定主表值的所有关联关系编号列表
     * @param mainId 主表编号
     * @return {@link List }<{@link S}>
     */
    List<S> subIds(M mainId);

    /**
     * 获取指定主表值所有关联关系编号列表
     * @return {@link List }<{@link S}>
     */
    default List<S> subIds() {
        return subIds(getMainId());
    }

    /**
     * 是否存在指定关系
     * @param mainId    主要编号
     * @param subIds     子编号
     * @return boolean
     */
    @SuppressWarnings("unchecked")
    default boolean exists(M mainId, S... subIds) {
        return exists(mainId, Arrays.asList(subIds));
    }

    /**
     * 是否存在指定关系
     * @param subIds     子编号
     * @return boolean
     */
    @SuppressWarnings("unchecked")
    default boolean exists(S... subIds) {
        return exists(getMainId(), subIds);
    }

    /**
     * 是否存在指定关系
     * @param mainId    主要编号
     * @param subIds     子编号
     * @return boolean
     */
    boolean exists(M mainId, Collection<? extends S> subIds);

    /**
     * 是否存在指定关系
     * @param subIds     子编号
     * @return boolean
     */
    default boolean exists(Collection<? extends S> subIds) {
        return exists(getMainId(), subIds);
    }

    /**
     * 计数（获取所有的指定主表值的所有关联关系数量）
     * @param mainId 主表编号
     * @return long
     */
    long count(M mainId);

    /**
     * 计数（获取所有的指定主表值的所有关联关系数量）
     * @return long
     */
    default long count() {
        return count(getMainId());
    }

    /**
     * 创造
     * @param mainId main编号
     * @param subId  子编号
     * @return {@link T }
     */
    T create(M mainId, S subId);

    /**
     * 创造
     * @param subId 子编号
     * @return {@link T }
     */
    default T create(S subId) {
        return create(getMainId(), subId);
    }

    /**
     * 创造
     * @param mainId    main编号
     * @param subIds    子 ID
     * @return {@link T }
     */
    @SuppressWarnings("unchecked")
    default List<T> create(M mainId, S... subIds) {
        return Arrays.stream(subIds).map(subId -> create(mainId, subId)).collect(Collectors.toList());
    }

    /**
     * 创造
     * @param subIds    子 ID
     * @return {@link T }
     */
    @SuppressWarnings("unchecked")
    default List<T> create(S... subIds) {
        return create(getMainId(), subIds);
    }

    /**
     * 创造
     * @param mainId    main编号
     * @param subIds    子 ID
     * @return {@link T }
     */
    default List<T> create(M mainId, Collection<? extends S> subIds) {
        return subIds.stream().map(subId -> create(mainId, subId)).collect(Collectors.toList());
    }

    /**
     * 创造
     * @param subIds    子 ID
     * @return {@link T }
     */
    default List<T> create(Collection<? extends S> subIds) {
        return create(getMainId(), subIds);
    }

}
